package entityData

import (
	"gitee.com/fierce_wolf/go-fox-edge-common/commSql"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Map"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/String"
	"gitee.com/fierce_wolf/go-next-entity/nextEntity"
)

type tag struct {
	MaxSize int
}

func (e *tag) HasSrcId(tableName, tagName string, dataset string, srcId int64) (bool, error) {
	list, err := e.GetRowIdBySrcId(tableName, tagName, dataset, srcId)
	if err != nil {
		return false, err
	}

	return len(list) > 0, nil
}

func (e *tag) GetRowIdBySrcId(tableName, tagName string, dataset string, srcId int64) ([]int64, error) {
	sql := "SELECT t.id FROM " + tableName + " t WHERE t.tag_name = ? AND t.`value`->'$." + dataset + ".ids.id" + String.ToString(srcId) + "' IS NOT NULL"

	fields := make([]commSql.FieldValue, 0)
	fields = append(fields, commSql.FieldValue{Name: "id", Value: 0})
	args := make([]interface{}, 0)
	args = append(args, tagName)

	list, err := commSql.Client.SQueryList(sql, fields, args)
	if err != nil {
		return nil, err
	}

	ids := make([]int64, 0)
	for _, val := range list {
		ids = append(ids, Map.GetInt64(val, "id", 0))
	}

	return ids, nil
}

func (e *tag) SaveSrcId(tableName, tagName string, dataset string, srcId int64) (int64, error) {
	// 预分配空间
	rowId, err := e.prepareSpace(tableName, tagName, dataset)
	if err != nil {
		return -1, err
	}

	// 保存该数据到空间
	err = e.saveSrcId(tableName, rowId, dataset, srcId)
	if err != nil {
		return rowId, err
	}

	return rowId, nil
}

func (e *tag) saveSrcId(tableName string, rowId int64, dataset string, srcId int64) error {
	String.ToString(srcId)
	sql := "UPDATE " + tableName + " SET `value` = JSON_SET(`value`, '$." + dataset + ".ids.id" + String.ToString(srcId) + "', NULL) WHERE id=" + String.ToString(rowId)
	_, err := commSql.Client.Exec(sql, nil)
	if err != nil {
		return err
	}

	return nil
}

func (e *tag) prepareSpace(tableName, tagName, dataset string) (int64, error) {
	maxSize := 0
	if e.MaxSize == 0 {
		maxSize = 10000
	}

	sql := "SELECT t.id FROM " + tableName + " t WHERE t.tag_name = ? AND JSON_LENGTH(JSON_KEYS(t.`value`->'$." + dataset + ".ids')) < " + String.ToString(maxSize) + " LIMIT 1"

	fields := make([]commSql.FieldValue, 0)
	fields = append(fields, commSql.FieldValue{Name: "id", Value: 0})
	args := make([]interface{}, 0)
	args = append(args, tagName)

	list, err := commSql.Client.SQueryList(sql, fields, args)
	if err != nil {
		return -1, err
	}
	if len(list) == 1 {
		return Map.GetInt64(list[0], "id", 0), nil
	}

	// 准备一条新的记录
	entity := nextEntity.Type.TagEntity.NewEntity().(*nextEntity.TagEntity)
	entity.TagName = tagName
	Map.SetValue(entity.Value, dataset, "ids", make(map[string]interface{}))
	err = commSql.InsertRecord(tableName, entity)
	if err != nil {
		return -1, err
	}

	return entity.BaseEntity.Id, nil
}
